/*---------------------------------------------------------------------------*
 * Copyright (C) 2012 Ryan M. Murphy <ryan.m.murphy.77@gmail.com>
 *
 * File Name   : usr_bms.h
 *
 * Project     : Watts-rock
 *               <http://code.google.com/p/watts-rock-motherboard/>
 *
 * Description : This file is responsible for performing the operations that
 *               make up the Watts-rock battery management system.
 *
 * Last Update : Oct, 18, 2012
 *---------------------------------------------------------------------------*/
#ifndef usr_bms_h

   #ifdef __cplusplus
   extern "C" {
   #endif

	/*------------------------------------------------------------------------*
	 * Global Defines
	 *------------------------------------------------------------------------*/
	#define usr_bms_h

	/*------------------------------------------------------------------------*
	 * Include Files
	 *------------------------------------------------------------------------*/
   #include "avr_compiler.h"
   #include "arb_error.h"
   #include "arb_mailbox.h"
   #include "drv_bms.h"
   #include "usr_bmsFault.h"

	/*------------------------------------------------------------------------*
	 * Global typedefs
	 *------------------------------------------------------------------------*/

	/*------------------------------------------------------------------------*
	 * This enum defines the possible states of the BMS.
	 *------------------------------------------------------------------------*/
   typedef enum
   {
      /*---------------------------------------------------------------------*
       * The processor has just come out of reset.
       *---------------------------------------------------------------------*/
      BMS_BOOT = 0,
      /*---------------------------------------------------------------------*
       * The battery is charging with the PAC off.
       *---------------------------------------------------------------------*/
      BMS_CHARGE_DEEP,
      /*---------------------------------------------------------------------*
       * The battery is charging with the PAC on.
       *---------------------------------------------------------------------*/
      BMS_CHARGE_NOM,
      /*---------------------------------------------------------------------*
       * The battery is running under nominal conditions.
       *---------------------------------------------------------------------*/
      BMS_NOMINAL,
      /*---------------------------------------------------------------------*
       * The battery has been discharged too much and the outputs have been
       * shut off.
       *---------------------------------------------------------------------*/
      BMS_DEEP_DIST,
      /*---------------------------------------------------------------------*
       * The BMS is preparing to power the motherboard down.
       *---------------------------------------------------------------------*/
      BMS_POWER_DOWN,
      /*---------------------------------------------------------------------*
       * The BMS has entered a fault state.
       *---------------------------------------------------------------------*/
      BMS_FAULT,
      /*---------------------------------------------------------------------*
       * This variable is always last.
       *---------------------------------------------------------------------*/
      BMS_NUM_STATES

   }t_bmsState;

	/*------------------------------------------------------------------------*
	 * This enum defines the set of external messages that can be sent back
    * and forth between the BMS and an external thread.
	 *------------------------------------------------------------------------*/
   typedef enum
   {
      /*---------------------------------------------------------------------*
       * Tells the BMS to transition into the 'BMS_POWER_DOWN' state.
       *---------------------------------------------------------------------*/
      BMS_CMD_PWR_DOWN = 0,
      /*---------------------------------------------------------------------*
       * Tells the BMS to configure the limits for its particular battery
       * chemistry.
       *---------------------------------------------------------------------*/
      BMS_CMD_SET_LIMITS,
      /*---------------------------------------------------------------------*
       * Returns the configuration limits for this particular BMS system
       *---------------------------------------------------------------------*/
      BMS_CMD_GET_LIMITS,
      /*---------------------------------------------------------------------*
       * Turn on/off the battery output to the outside world.
       *---------------------------------------------------------------------*/
      BMS_CMD_PACK_CNTRL,
      /*---------------------------------------------------------------------*
       * A fault has been confirmed-assuming fixed- by an external user.
       *---------------------------------------------------------------------*/
      BMS_CMD_FAULT_ACK,
      /*---------------------------------------------------------------------*
       * Requests the BMS's last known voltage, current, temperature and
       * operational state.
       *---------------------------------------------------------------------*/
      BMS_CMD_GET_STATE,
      /*---------------------------------------------------------------------*
       * Sets the energy left in the battery (Coulomb count level).
       *---------------------------------------------------------------------*/
      BMS_CMD_SET_CMB_CNT,
      /*---------------------------------------------------------------------*
       * Returns the BMS's last known voltage, current, temperature and
       * operational state in response to a BMS_CMD_GET_STATE message.
       *---------------------------------------------------------------------*/
      BMS_CMD_CURR_STATE,
      /*---------------------------------------------------------------------*
       * Sets the serial number for the particular battery this BMS is
       * attached to.
       *---------------------------------------------------------------------*/
      BMS_CMD_SET_BATT_SERIAL_NUM,
      /*---------------------------------------------------------------------*
       * Sets the serial number for the BMS board this particular software
       * is operating on.
       *---------------------------------------------------------------------*/
      BMS_CMD_SET_BOARD_SERIAL_NUM,
      /*---------------------------------------------------------------------*
       * Turn on/off the fan.
       *---------------------------------------------------------------------*/
      BMS_CMD_FAN_CNTRL

   }t_bmsMsgId;

	/*------------------------------------------------------------------------*
	 * This structure contains the variables for setting the battery limits
    * for this particular BMS.
	 *------------------------------------------------------------------------*/
   typedef struct
   {
      /*---------------------------------------------------------------------*
       * The level at which the battery is empty.
       *---------------------------------------------------------------------*/
      float f_lowVoltageThr;
      /*---------------------------------------------------------------------*
       * The level at which the battery is full.
       *---------------------------------------------------------------------*/
      float f_highVoltageThr;
      /*---------------------------------------------------------------------*
       * The level at which the 'pack' output is shut off (in order to prevent
       * damage) due to an external device pulling too much current.
       *---------------------------------------------------------------------*/
      float f_highCurrThr;
      /*---------------------------------------------------------------------*
       * The level at which the 'pack' output is shut off (in order to prevent
       * damage) due to the internal battery chamber temperature getting too
       * hot.
       *---------------------------------------------------------------------*/
      float f_highTempThr;
      /*---------------------------------------------------------------------*
       * The amount of hysteresis on the voltage measurement used for preventing
       * thrashing when transitioning between the various BMS states.
       *---------------------------------------------------------------------*/
      float f_voltHyst;
      /*---------------------------------------------------------------------*
       * The amount of hysteresis on the temp measurement used for preventing
       * thrashing when transitioning between the various BMS states.
       *---------------------------------------------------------------------*/
      float f_tempHyst;
      /*---------------------------------------------------------------------*
       * The energy density of the particular battery the BMS is paired with.
       *---------------------------------------------------------------------*/
      float f_battAmpHours;
      /*---------------------------------------------------------------------*
       * The maximum charge current for the particular battery this BMS is
       * managing.
       *---------------------------------------------------------------------*/
      float f_maxChargeCurrent;

   }t_bmsLimits;

	/*------------------------------------------------------------------------*
	 * This structure defines the variables for exchanging the status of the
    * BMS with the outside world.
	 *------------------------------------------------------------------------*/
   typedef struct
   {
	   /*---------------------------------------------------------------------*
	    * The last known voltage, current, and temperature measurement.
	    *---------------------------------------------------------------------*/
      t_bmsMeas t_meas;
	   /*---------------------------------------------------------------------*
	    * The last known BMS state.
	    *---------------------------------------------------------------------*/
      t_bmsState t_state;
      /*---------------------------------------------------------------------*
       * The percentage of energy left in the battery.
       *---------------------------------------------------------------------*/
      float f_gasGuage;
      /*---------------------------------------------------------------------*
       * The fault status where,
       *              .---.---.---.---.---.---.---.---.
       *    c_fault = | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
       *              '---'---'---'---'---'---'---'---'
       *                            |   |   |   |   |
       *                            |   |   |   |   '-->BMS_FAULT_CURRENT
       *                            |   |   |   '------>BMS_FAULT_TEMP
       *                            |   |   '---------->BMS_FAULT_NO_BATT
       *                            |   '-------------->BMS_FAULT_CHARGE
       *                            '------------------>BMS_FAULT_RAPID_TEMP
       *---------------------------------------------------------------------*/
      uint8_t c_fault;

   }t_bmsMeasStatus;

	/*------------------------------------------------------------------------*
	 * This message contains the variables required for turning on/off the
    * battery output (PAC) via an external user interface.
	 *------------------------------------------------------------------------*/
   typedef struct
   {
	   /*---------------------------------------------------------------------*
	    * The ID for this particular message (BMS_CMD_PACK_CNTRL)
	    *---------------------------------------------------------------------*/
      uint8_t c_msgId;

	   /*---------------------------------------------------------------------*
	    * If true, the PAC output is on, otherwise its off.
	    *---------------------------------------------------------------------*/
      bool b_enabled;

   }t_bmsPacCntrlMsg;

	/*------------------------------------------------------------------------*
	 * This message contains the variables required for turning on/off the
    * fan.
	 *------------------------------------------------------------------------*/
   typedef struct
   {
	   /*---------------------------------------------------------------------*
	    * The ID for this particular message (BMS_CMD_FAN_CNTRL)
	    *---------------------------------------------------------------------*/
      uint8_t c_msgId;

	   /*---------------------------------------------------------------------*
	    * If true, the fan is on, otherwise off.
	    *---------------------------------------------------------------------*/
      bool b_enabled;

   }t_bmsFanCntrlMsg;

	/*------------------------------------------------------------------------*
	 * This message contains the variables required for setting the voltage,
    * current, and temperature limits for the BMS.
	 *------------------------------------------------------------------------*/
   typedef struct
   {
	   /*---------------------------------------------------------------------*
	    * The ID for this particular message (BMS_CMD_SET_LIMITS)
	    *---------------------------------------------------------------------*/
      uint8_t c_msgId;

	   /*---------------------------------------------------------------------*
	    * The voltage, current, and temperature limits for this particular BMS.
	    *---------------------------------------------------------------------*/
      t_bmsLimits t_limits;

   }t_bmsSetLimitsMsg;

	/*------------------------------------------------------------------------*
	 * This message sets the serial number for a particular battery this BMS
    * is monitoring.
	 *------------------------------------------------------------------------*/
   typedef struct
   {
	   /*---------------------------------------------------------------------*
	    * The ID for this particular message (BMS_CMD_SET_BATT_SERIAL_NUM)
	    *---------------------------------------------------------------------*/
      uint8_t c_msgId;

	   /*---------------------------------------------------------------------*
	    * The battery serial number.
	    *---------------------------------------------------------------------*/
      uint32_t i_battSerialNum;

   }t_bmsSetBattSerialNumMsg;

	/*------------------------------------------------------------------------*
	 * This message sets the BMS board serial number
	 *------------------------------------------------------------------------*/
   typedef struct
   {
	   /*---------------------------------------------------------------------*
	    * The ID for this particular message (BMS_CMD_SET_BOARD_SERIAL_NUM)
	    *---------------------------------------------------------------------*/
      uint8_t c_msgId;

	   /*---------------------------------------------------------------------*
	    * The board serial number.
	    *---------------------------------------------------------------------*/
      uint32_t i_boardSerialNum;

   }t_bmsSetBoardSerialNumMsg;

	/*------------------------------------------------------------------------*
	 * This message lets the BMS know that a fault condition has been
    * acknowledged by an external user.
	 *------------------------------------------------------------------------*/
   typedef struct
   {
	   /*---------------------------------------------------------------------*
	    * The ID for this particular message (BMS_CMD_FAULT_ACK)
	    *---------------------------------------------------------------------*/
      uint8_t c_msgId;

   }t_bmsFaultAckMsg;

	/*------------------------------------------------------------------------*
	 * This message lets the BMS know that an external user wants it to
    * power down.
	 *------------------------------------------------------------------------*/
   typedef struct
   {
	   /*---------------------------------------------------------------------*
	    * The ID for this particular message (BMS_CMD_PWR_DOWN)
	    *---------------------------------------------------------------------*/
      uint8_t c_msgId;

   }t_bmsPwrDownMsg;

	/*------------------------------------------------------------------------*
	 * This message returns the last known BMS voltage, current, temperature,
    * and operational state in response to a BMS_CMD_GET_STATE message.
	 *------------------------------------------------------------------------*/
   typedef struct
   {
	   /*---------------------------------------------------------------------*
	    * The ID for this particular message (BMS_CMD_CURR_STATE)
	    *---------------------------------------------------------------------*/
      uint8_t c_msgId;

      t_bmsMeasStatus t_state;

   }t_bmsCurrStateMsg;

	/*------------------------------------------------------------------------*
	 * This message sets the battery energy level (Coulomb count).
	 *------------------------------------------------------------------------*/
   typedef struct
   {
	   /*---------------------------------------------------------------------*
	    * The ID for this particular message (BMS_CMD_SET_CMB_CNT)
	    *---------------------------------------------------------------------*/
      uint8_t c_msgId;

      float f_percFull;

   }t_bmsSetCmbCntMsg;

	/*------------------------------------------------------------------------*
	 * Global Variables
	 *------------------------------------------------------------------------*/

	/*------------------------------------------------------------------------*
	 * Global Function Prototypes
	 *------------------------------------------------------------------------*/
   t_error usr_bmsInit( void);

   /*------------------------------------------------------------------------*
    * Returns the last known battery voltage, current, temperature, fuel gage
    * and BMS state.
    *------------------------------------------------------------------------*/
   t_bmsMeasStatus usr_getBmsMeas( void);

   /*------------------------------------------------------------------------*
    * Returns the last known battery voltage, current, and temperature,
    * limits for the system.
    *------------------------------------------------------------------------*/
   t_bmsLimits *usr_getBmsLimits( void);

   /*------------------------------------------------------------------------*
    * Configures the Coulomb count.
    *------------------------------------------------------------------------*/
   bool usr_setBmsSetCoulombCount( float f_perc);

   /*------------------------------------------------------------------------*
    * This function returns the mailbox handle for sending messages to the BMS.
    *------------------------------------------------------------------------*/
   t_MAILBOXHNDL usr_getBmsInMlbxHndle( void);

   /*------------------------------------------------------------------------*
    * This function returns the mailbox handle for receiving messages from the
    * BMS.
    *------------------------------------------------------------------------*/
   t_MAILBOXHNDL usr_getBmsOutMlbxHndle( void);

   #ifdef __cplusplus
   }/*End extern "C"*/
   #endif

#endif/*End #ifndef usr_bms_h*/
